﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

using System.Windows.Media;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Graph = Microsoft.Office.Interop.Graph;
using System.Runtime.InteropServices;
using Microsoft.Office.Core;
using System.Windows.Forms;
namespace DataLayer
{
    public class Node : SystemFile
    {
        int level = 0;

        public int Level
        {
            get { return level; }
            set { level = value; }
        }
        string strOrder = "";

        public string StrOrder
        {
            get { return strOrder; }
            set { strOrder = value; }
        }

        private int order = 0;

        public int Order
        {
            get { return order; }
            set {
                order = value;
                if(parentNode != null)
                     strOrder = parentNode.StrOrder + "." + order.ToString();
                //strOrder = strColor + order.ToString();
                else
                    strOrder = order.ToString();
            }
        }
        private int direction = 0;

        public int Direction
        {
            get { return direction; }
            set { direction = value; }
        }
        protected bool isfirst = true;

        public bool Isfirst
        {
            get { return isfirst; }
            set { isfirst = value; }
        }
       protected double y = 250;

        public double Y
        {
            get { return y; }
            set { y = value;
            this.Isfirst = false;
            }
        }

        protected double x = 500;

        public double X
        {
            get { return x; }
            set {
                x = value;
                this.Isfirst = false;
            }
        }
        protected bool isSelected = false;

        public bool IsSelected
        {
            get { return isSelected; }
            set { isSelected = value; }
        }
        CheckChildNodeCommand childNodeCommand;
        CheckContentNodeCommand contentCommand;
        CheckNodeLevelCommand levelCommand;
        bool isExpanded;

        public bool IsExpanded
        {
            get { return isExpanded; }
            set { isExpanded = value; }
        }
        List<int> errorList;

        public List<int> ErrorList
        {
            get { return errorList; }
            set { errorList = value; }
        }
        Color color ;

        public Color Color
        {
            get { return color; }
            set {
                color = value;
                strColor = color.ToString();
            }
        }
        string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        List<Node> childrenNodeList;

        public List<Node> ChildrenNodeList
        {
            get { return childrenNodeList; }
            set { childrenNodeList = value; }
        }

        List<Icon> iconList;

        protected List<Icon> IconList
        {
            get { return iconList; }
            set { iconList = value; }
        }

        List<int> sourceIDList;

        protected List<int> SourceIDList
        {
            get { return sourceIDList; }
            set { sourceIDList = value; }
        }



        List<NodeContent> contentList;

        public List<NodeContent> ContentList
        {
            get { return contentList; }
            set { contentList = value; }
        }
        Node parentNode;

        public Node ParentNode
        {
            get { return parentNode; }
            set { parentNode = value; }
        }
        public Node()
        {
            this.IsExpanded = true;
            this.childrenNodeList = new List<Node>();
            this.contentList = new List<NodeContent>();
            this.iconList = new List<Icon>();
            this.sourceIDList = new List<int>();
            this.childNodeCommand = new CheckChildNodeCommand(this);
            this.contentCommand = new CheckContentNodeCommand(this);
            this.levelCommand = new CheckNodeLevelCommand(this);
            order = 1;
        }

        

        public string NodePath()
        {
            string result="";
            List<string> list = new List<string>();
            list.Add(this.name);
            Node tempNode=this;
            while (tempNode.parentNode != null)
            {
                tempNode = tempNode.parentNode;
                list.Add(tempNode.name);
            }
            for (int i =  ( list.Count-1 ); i >= 0; i--)
            { 
                result+=list[i]+"/";
            }
            return result;
        }
        public void CopyData(Node _node)
        {
             this.childrenNodeList = new List<Node>();
            this.contentList = new List<NodeContent>();
            this.iconList = new List<Icon>();
            this.sourceIDList = new List<int>();
            this.X = _node.X;
            this.Y = _node.Y;
            this.direction = _node.direction;
            this.name = _node.Name;
            this.Color = _node.Color;
            this.childNodeCommand = new CheckChildNodeCommand(this);
            this.contentCommand = new CheckContentNodeCommand(this);
            this.levelCommand = new CheckNodeLevelCommand(this);
            this.parentNode = _node.ParentNode;
            for (int i = 0; i < _node.ContentList.Count; i++)
            {
                this.AddContent(_node.ContentList[i]);
            }

            for (int i = 0; i < _node.childrenNodeList.Count; i++)
            {
                Node item = new Node(_node.childrenNodeList[i]);
                this.AddNode(item);               
            }

            for (int i = 0; i < _node.iconList.Count; i++)
            {
                this.iconList.Add(_node.iconList[i]);
            }

            for (int i = 0; i < _node.sourceIDList.Count; i++)
            {
                this.sourceIDList.Add(_node.sourceIDList[i]);
            }
          
        }
        public Node(Node _node)
        {
            CopyData(_node);
        }

        const int left = 1;
        const int right = 2;
        public int CountRightChildeNode()
        {
            int rs = 0;
            foreach (Node node in this.childrenNodeList)
            {
                if (node.direction == right)
                {
                    rs++;
                }
            }
            return rs;
        }
        public void InitNode(XmlNode _xmlnode,string _relativePath)
        {
            if (_xmlnode.Attributes["expand"] != null)
            {
                string expand = _xmlnode.Attributes["expand"].Value;
                bool ex = bool.Parse(expand);
                this.IsExpanded = ex;
            }
            else
            {
                this.isExpanded = true;
            }

            string name = _xmlnode.Attributes["name"].Value;
            string strColor = _xmlnode.Attributes["color"].Value;
            if (_xmlnode.Attributes["x"] != null)
            {
                double _x = double.Parse(_xmlnode.Attributes["x"].Value);
                this.x = _x;
            }
            if (_xmlnode.Attributes["y"] != null)
            {
                double _y = double.Parse(_xmlnode.Attributes["y"].Value);
                this.y = _y;
            }
            if (_xmlnode.Attributes["direction"] != null)
            {
                this.direction = int.Parse(_xmlnode.Attributes["direction"].Value);
            }
            Color color = (Color)ColorConverter.ConvertFromString(strColor);
            
            
 
            this.Name = name;
            this.Color = color;
            XmlNodeList _xmlnodelist = _xmlnode.ChildNodes;//cac thanh phan trong 1 node
            for (int i = 0; i < _xmlnodelist.Count; i++)
            {
                string nodename = _xmlnodelist[i].Name;
                int nodecount = _xmlnodelist[i].ChildNodes.Count;
                if (nodename == "nodelist")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        Node childnode = new Node();
                        childnode.parentNode = this;
                        childnode.InitNode(xmlchildnode, _relativePath);                        
                        this.AddNode(childnode);
                        childnode.ParentNode = this;
                    }
                }
                if (nodename == "sourceIdList")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        int source = int.Parse(xmlchildnode.InnerText);
                        this.sourceIDList.Add(source);
                    }
                }
                if (nodename == "iconList")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        int id = int.Parse(xmlchildnode.InnerText);
                        this.iconList.Add((new IconsHelper()).GetIconById(id));
                    }
                    if (this.iconList.Count != 0)
                        Order = iconList[0].Id;
                }
                if (nodename == "contentList")
                {
                    this.contentList = NodeContent.LoadContentFromXmlNode(_xmlnodelist[i], this, _relativePath);
                    this.contentCommand.Excute();
                }
                if (nodename == "errorList")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        int value = int.Parse(xmlchildnode.InnerText);
                        this.sourceIDList.Add(value);
                    }
                }
            }
            this.isfirst = false;
        }

        public void InitNode(XmlNode _xmlnode, ref int percent, string _relativePath)
        {
            string name = _xmlnode.Attributes["name"].Value;
            string strColor = _xmlnode.Attributes["color"].Value;
            Color color = (Color)ColorConverter.ConvertFromString(strColor);

            this.Name = name;
            this.Color = color;
            XmlNodeList _xmlnodelist = _xmlnode.ChildNodes;//cac thanh phan trong 1 node

            for (int i = 0; i < _xmlnodelist.Count; i++)
            {
                percent += 20;
                string nodename = _xmlnodelist[i].Name;
                int nodecount = _xmlnodelist[i].ChildNodes.Count;
                if (nodename == "nodelist")
                {

                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        Node childnode = new Node();
                        childnode.parentNode = this;
                        childnode.InitNode(xmlchildnode, _relativePath);
                        
                        this.AddNode(childnode);
                        childnode.parentNode = this;
                    }
                    if (this.iconList.Count != 0)
                        Order = iconList[0].Id;
                }
                if (nodename == "sourceIdList")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        int source = int.Parse(xmlchildnode.InnerText);
                        this.sourceIDList.Add(source);
                    }
                }
                if (nodename == "iconList")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        int id = int.Parse(xmlchildnode.InnerText);
                        this.iconList.Add((new IconsHelper()).GetIconById(id));
                    }
                    if (this.iconList.Count != 0)
                        Order = iconList[0].Id;
                }
                if (nodename == "contentList")
                {
                    this.contentList = NodeContent.LoadContentFromXmlNode(_xmlnodelist[i], this, _relativePath);
                    this.contentCommand.Excute();
                }
                if (nodename == "errorList")
                {
                    for (int j = 0; j < nodecount; j++)
                    {
                        XmlNode xmlchildnode = _xmlnodelist[i].ChildNodes[j];
                        int value = int.Parse(xmlchildnode.InnerText);
                        this.sourceIDList.Add(value);
                    }
                }
                
            }
            percent = 100;
        }
        

        public void AddNode(Node _node)
        {
            bool isExist = false;
            foreach (Node childe in this.ChildrenNodeList)
            {
                if (childe.Name.Equals(_node.Name))
                {
                    isExist = true;
                    return;
                }
            }
            if (!isExist)
            {
                this.childrenNodeList.Add(_node);
                _node.ParentNode = this;
                this.childNodeCommand.Excute();
                this.levelCommand.Excute();
            }
        }

        public void AddError(int _error)
        {
            if (this.errorList != null)
            {
                int isExist = 0;
                for (int i = 0; i < this.errorList.Count; i++)
                {
                    if (this.errorList[i] == _error)
                    {
                        isExist++;
                    }
                }
                if (isExist == 0)
                    this.errorList.Add(_error);
            }
            else
            {
                this.errorList = new List<int>();
                errorList.Add(_error);
            }
        }

        public void AddIcon(Icon _icon)
        {
            if (this.iconList != null)
            {
                this.iconList.Add(_icon);
            }
        }

        public void AddContent(NodeContent _content)
        {
            if (this.contentList != null)
            {
                this.contentList.Add(_content);
                this.contentCommand.Excute();
                _content.Parent = this;
            }
        }

        public void AddSourceId(int _id)
        {
            if (this.sourceIDList != null)
            {
                this.sourceIDList.Add(_id);
            }
        }

        public void CheckAndChangeName(List<Node> compList)
        {
            foreach (Node item in compList)
            {
                int itemId = 0;
                string rootName = this.Name;
                string newName = rootName;
                do
                {
                    if (item.Name.Equals(newName))
                    {
                        itemId++;
                        newName = rootName + " (" + itemId + ")";
                    }
                    else
                        itemId = 0;
                } while (itemId != 0);
                this.Name = newName;
            }
        }

        public List<Node> FindNodesByLevel(int _level)
        {
            if (_level == 0)
                return this.childrenNodeList;
            return this.FindNodesByLevel(_level -1);
        }

        public List<Node> FindChildNodes()
        {
            return this.childrenNodeList;
        }

        public void FindDescendants(List<Node> rsList)
        {
            //rsList.AddRange(this.childrenNodeList);
            foreach (Node item in this.childrenNodeList)
            {
                rsList.Add(item);
                item.FindDescendants(rsList);
            }
        }
        public void InsertNode(int _level, Node _node)
        {
            if (_level == 1)
            {
                this.AddNode(_node);
            }
            if (_level > 1)
            {
                this.InsertNode(_level - 1, _node);
            }
        }

        public virtual void RemoveNode(string _name)
        {
            int count = this.childrenNodeList.Count;
            for (int i = 0; i < count; i++)
            {
                if (this.childrenNodeList[i].name == _name)
                {
                    this.childrenNodeList.RemoveAt(i);
                    i--;
                    count--;
                }
                else
                {
                    this.childrenNodeList[i].RemoveNode(_name);
                }
            }
        }
        public Node GetNodeByName(string name)
        {
            if (this.name == name)
                return this;
            else
            {
                int count = this.childrenNodeList.Count;
                for (int i = 0; i < count; i++)
                {
                    if (this.childrenNodeList[i].GetNodeByName(name)!=null)
                        return this.childrenNodeList[i].GetNodeByName(name);
                }
            }
            return null;
        }


        public void GetNodesAfter(List<Node> listRs)
        {
            if (childrenNodeList != null)
            {
                int count = this.childrenNodeList.Count;
                for (int i = 0; i < count; i++)
                {
                    listRs.Add(childrenNodeList[i]);
                    childrenNodeList[i].GetNodesAfter(listRs);
                }
            }
        }

       
        virtual public void AddToXmlDoc(XmlDocument _doc, XmlElement node)
        {
            int count = 0;
            XmlNode e;
            if (childrenNodeList != null && this.childrenNodeList.Count!=0)
            {                
                count = this.childrenNodeList.Count;
                e = node.AppendChild(_doc.CreateElement("nodelist"));                
                for (int i = 0; i < count; i++)
                {
                    XmlElement childnode = _doc.CreateElement("node");
                    XmlAttribute nameAtt = _doc.CreateAttribute("name");
                    nameAtt.Value = childrenNodeList[i].Name;
                    XmlAttribute xAtt = _doc.CreateAttribute("x");
                    xAtt.Value = childrenNodeList[i].X.ToString();
                    XmlAttribute yAtt = _doc.CreateAttribute("y");
                    yAtt.Value = childrenNodeList[i].y.ToString() ;
                    XmlAttribute dirAtt = _doc.CreateAttribute("direction");
                    dirAtt.Value = childrenNodeList[i].direction.ToString();
                    XmlAttribute expandAtt = _doc.CreateAttribute("expand");
                    expandAtt.Value = childrenNodeList[i].IsExpanded.ToString();
                    XmlAttribute color = _doc.CreateAttribute("color");
                    color.Value = childrenNodeList[i].Color.ToString();
                    childnode.Attributes.Append(nameAtt);
                    childnode.Attributes.Append(expandAtt);
                    childnode.Attributes.Append(color);
                    childnode.Attributes.Append(xAtt);
                    childnode.Attributes.Append(yAtt);
                    childnode.Attributes.Append(dirAtt);
                
                    childrenNodeList[i].AddToXmlDoc(_doc, childnode);
                    e.AppendChild(childnode);
                }
                node.AppendChild(e);
            }
            if (iconList != null && this.iconList.Count != 0)
            {
                e = node.AppendChild(_doc.CreateElement("iconList"));
                count = this.iconList.Count;
                XmlElement element = _doc.CreateElement("icon");
                element.InnerText = Order.ToString();
                e.AppendChild(element);
                for (int i = 1; i < count; i++)
                {
                    if (this.iconList[i] != null)
                    {
                        element = _doc.CreateElement("icon");
                        element.InnerText = this.iconList[i].Id.ToString();
                        e.AppendChild(element);
                    }
                }
                node.AppendChild(e);
            }
            else
            {
                e = node.AppendChild(_doc.CreateElement("iconList"));
                XmlElement element = _doc.CreateElement("icon");
                element.InnerText = Order.ToString();
                e.AppendChild(element);
            }
            if(sourceIDList != null && this.SourceIDList.Count != 0)
            {
                 e =  node.AppendChild(_doc.CreateElement("sourceIdList"));

                 count = this.sourceIDList.Count;
                for (int i = 0; i < count; i++)
                {
                    XmlElement element = _doc.CreateElement("sourceID");
                    element.InnerText = this.sourceIDList[i].ToString();
                    e.AppendChild(element);
                }

                node.AppendChild(e);
            }
            if (errorList != null && this.errorList.Count != 0)
            {
                e = node.AppendChild(_doc.CreateElement("errorList"));

                count = this.errorList.Count;
                for (int i = 0; i < count; i++)
                {
                    XmlElement element = _doc.CreateElement("Error");
                    element.InnerText = this.errorList[i].ToString();
                    e.AppendChild(element);
                }

                node.AppendChild(e);
            }
            if(contentList != null && this.contentList.Count != 0)
            {
                 e =  node.AppendChild(_doc.CreateElement("contentList"));
                count = this.contentList.Count;
                for (int i = 0; i < count; i++)
                {
                    XmlElement element = _doc.CreateElement("content");
                    XmlAttribute typeAtt = _doc.CreateAttribute("type");
                    XmlAttribute leftAtt = _doc.CreateAttribute("left");
                    leftAtt.Value = contentList[i].Left.ToString();
                    element.Attributes.Append(leftAtt);

                    XmlAttribute topAtt = _doc.CreateAttribute("top");
                    topAtt.Value = contentList[i].Top.ToString();
                    element.Attributes.Append(topAtt);

                    XmlAttribute widthAtt = _doc.CreateAttribute("width");
                    widthAtt.Value = contentList[i].Width.ToString();
                    element.Attributes.Append(widthAtt);

                    XmlAttribute heightAtt = _doc.CreateAttribute("height");
                    heightAtt.Value = contentList[i].Height.ToString();
                    element.Attributes.Append(heightAtt);

                    if (this.contentList[i].Type == "text")
                    {
                        typeAtt.Value = "text";
                        element.Attributes.Append(typeAtt);
                        for (int p = 0; p < (this.contentList[i] as TextContent).ListParagraph.Count; p++)
                        {
                            Paragraph para = (this.contentList[i] as TextContent).ListParagraph[p];
                            XmlElement paraElement = _doc.CreateElement("paragraph");
                            XmlAttribute fontSizeAtt = _doc.CreateAttribute("fontSize");
                            fontSizeAtt.Value = para.FontSize.ToString();
                            paraElement.Attributes.Append(fontSizeAtt);

                            XmlAttribute fontNameAtt = _doc.CreateAttribute("fontName");
                            fontNameAtt.Value = para.FontName;
                            paraElement.Attributes.Append(fontNameAtt);

                            XmlAttribute colorAtt = _doc.CreateAttribute("color");
                            colorAtt.Value = para.Color.ToString();
                            paraElement.Attributes.Append(colorAtt);

                            XmlAttribute bulletType = _doc.CreateAttribute("bulletType");
                            bulletType.Value = para.BulletType.ToString();
                            paraElement.Attributes.Append(bulletType);

                            XmlAttribute bulletValue = _doc.CreateAttribute("bulletValue");
                            bulletValue.Value = para.BulletValue.ToString();
                            paraElement.Attributes.Append(bulletValue);

                            XmlAttribute indentAtt = _doc.CreateAttribute("indentLevel");
                            indentAtt.Value = para.IndentLevel.ToString();
                            paraElement.Attributes.Append(indentAtt);

                            paraElement.InnerText = para.Content;
                            element.AppendChild(paraElement);
                        }
                        
                        XmlAttribute alignAtt = _doc.CreateAttribute("alignment");
                        alignAtt.Value = ((TextContent)contentList[i]).Alignment.ToString();
                        element.Attributes.Append(alignAtt);               


                    }
                    else
                    {
                        typeAtt.Value = "image";
                        element.Attributes.Append(typeAtt);
                        element.InnerText = ((ImageContent)contentList[i]).GetRelativePath();
                    }
                    e.AppendChild(element);
                }
                node.AppendChild(e);                
            }
        }

        private float CalculateXContent(ref float currX, ref float currY)
        {
            float rs = currX;
            if (currX >= 500)
            {
                currY += 110;
                rs = currX = 10;
            }
            else
            {
                rs += 110;
                currX = rs;
            }

            return rs;
        }

        public int ComputeWidth()
        {
            return this.name.Length * 9;
        }
        

        public void AddNodeToSlide(PowerPoint.Slides objSlides, ref int indexslide,int currLevel, int level)
        {
            if (currLevel > level)
            {
                indexslide--;
                return;
            }
            PowerPoint.Slide objSlide = objSlides.Add( indexslide, PowerPoint.PpSlideLayout.ppLayoutTitleOnly);

            PowerPoint.TextRange objTextRng = objSlide.Shapes[1].TextFrame.TextRange;

            objTextRng.Text = this.name;

            objTextRng.Font.Name = "Comic Sans MS";

            objTextRng.Font.Size = 48;

            System.Windows.Forms.RichTextBox textbox = new RichTextBox();
            float currX = -100;
            float currY = 150;
            float textcurrY = 350;

            if (this.contentList != null && contentList.Count != 0)
            {
                int count = this.contentList.Count;
                for (int i = 0; i < count; i++)
                {
                    if (this.contentList[i].Type == "image")
                    {
                        string imagePath = ((ImageContent)contentList[i]).ImagePath;
                        if (System.IO.File.Exists(imagePath))
                        {
                            ImageContent imageContent = (ImageContent)contentList[i];
                            if (imageContent.Left == 0)
                            {
                                imageContent.Left = CalculateXContent(ref currX, ref currY);
                            }
                            if (imageContent.Top == 0)
                                imageContent.Top = currY;
                            if (imageContent.Width == 0)
                                imageContent.Width = 100;
                            if (imageContent.Height == 0)
                                imageContent.Height = 100;
                            objSlide.Shapes.AddPicture(imagePath, MsoTriState.msoFalse,
                                MsoTriState.msoTrue, imageContent.Left, imageContent.Top
                                , imageContent.Width, imageContent.Height);
                        }
                    }
                    else
                    {
                        TextContent textcontent = (TextContent)contentList[i];
                        if (textcontent.Left == 0)
                            textcontent.Left = 10;
                        if (textcontent.Top == 0)
                            textcontent.Top = textcurrY;
                        if (textcontent.Width == 0)
                            textcontent.Width = 650;
                        if (textcontent.Height == 0)
                            textcontent.Height = 100;

                        PowerPoint.Shape text = objSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, textcontent.Left, textcontent.Top,
                            textcontent.Width, textcontent.Height);

                        for (int j = 0; j < (contentList[i] as TextContent).ListParagraph.Count; j++)
                        {
                            Paragraph myparagraph = (contentList[i] as TextContent).ListParagraph[j];
                            if (myparagraph.Content.Length <= 0)
                                continue;
                            textbox.Clear();
                            textbox.Rtf = myparagraph.Content;
                            string str = textbox.Text.Trim();
                            PowerPoint.TextRange paragraph = text.TextFrame.TextRange.InsertAfter(str);
                            paragraph.IndentLevel = myparagraph.IndentLevel;
                            paragraph.Font.Name = myparagraph.FontName;
                            paragraph.Font.Size = myparagraph.FontSize;
                            paragraph.Font.Color.RGB = myparagraph.Color;
                            switch (myparagraph.BulletType)
                            {
                                case 0:
                                    paragraph.ParagraphFormat.Bullet.Type = PowerPoint.PpBulletType.ppBulletNone;
                                    break;
                                case 1:
                                    paragraph.ParagraphFormat.Bullet.Type = PowerPoint.PpBulletType.ppBulletNumbered;
                                   
                                    break;
                                case 2:
                                    paragraph.ParagraphFormat.Bullet.Type = PowerPoint.PpBulletType.ppBulletUnnumbered;
                                    paragraph.ParagraphFormat.Bullet.Character = myparagraph.BulletValue;
                                    break;
                            }

                        }

                        switch (((TextContent)contentList[i]).Alignment)
                        {
                            case 0:
                                text.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentLeft;
                                break;
                            case 1:
                                text.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered;
                                break;
                            case 2:
                                text.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentRight;
                                break;
                        }
                        textcurrY += text.Height;
                    }
                }
            }
            if (this.childrenNodeList != null)
            {
                int count = this.childrenNodeList.Count;
                for (int i = 0; i < count; i++)
                {
                    indexslide++;
                    this.childrenNodeList[i].AddNodeToSlide(objSlides, ref indexslide,currLevel+1,level);
                }
            }
        }

       virtual public void AddNodeToSlide(PowerPoint.Slides objSlides,ref int indexslide)
        {
            PowerPoint.Slide objSlide = objSlides.Add(indexslide, PowerPoint.PpSlideLayout.ppLayoutText);
           
            PowerPoint.TextRange objTextRng = objSlide.Shapes[1].TextFrame.TextRange;

            objTextRng.Text = this.name;

            objTextRng.Font.Name = "Comic Sans MS";

            objTextRng.Font.Size = 48;

           System.Windows.Forms.RichTextBox textbox = new RichTextBox();
           float currX = -100;
           float currY = 300;
           float textcurrY = 350;
            
            if (this.contentList != null && contentList.Count != 0)
            {
                int count = this.contentList.Count;
                for (int i = 0; i < count; i++)
                {
                    
                    if (this.contentList[i].Type.ToLower() == "image")
                    {
                        string imagePath = ((ImageContent)contentList[i]).ImagePath;
                        if(System.IO.File.Exists(imagePath))                        
                        {
                            ImageContent imageContent = (ImageContent)contentList[i];
                            if (imageContent.Left == 0)
                            {
                                imageContent.Left = CalculateXContent(ref currX, ref currY);
                            }
                            if (imageContent.Top == 0)
                                imageContent.Top = currY;
                            if (imageContent.Width == 0)
                                imageContent.Width = 100;
                            if (imageContent.Height == 0)
                                imageContent.Height = 100;

                            objSlide.Shapes.AddPicture(imagePath, MsoTriState.msoFalse,
                                MsoTriState.msoTrue, imageContent.Left, imageContent.Top
                                , imageContent.Width, imageContent.Height);
                        }
                    }
                    else
                    {
                        TextContent textcontent = (TextContent)contentList[i];
                        if (textcontent.Left == 0)
                            textcontent.Left = 10;
                        if (textcontent.Top == 0)
                            textcontent.Top = textcurrY;
                        if (textcontent.Width == 0)
                            textcontent.Width = 650;
                        if (textcontent.Height == 0)
                            textcontent.Height = 100;
                        PowerPoint.Shape text = objSlide.Shapes[2];            

                       
                       for (int j = 0; j < (contentList[i] as TextContent).ListParagraph.Count; j++)
                       {
                           Paragraph myparagraph = (contentList[i] as TextContent).ListParagraph[j];
                           if (myparagraph.Content.Length <= 0)
                               continue;
                           textbox.Clear();
                           
                           textbox.Rtf = myparagraph.Content;
                           string str = textbox.Text.Trim() + "\n";
                           PowerPoint.TextRange paragraph = text.TextFrame.TextRange.InsertAfter(str);
                           
                           paragraph.IndentLevel = myparagraph.IndentLevel;
                           
                           switch (myparagraph.BulletType)
                           {
                               case 1:
                                   paragraph.ParagraphFormat.Bullet.Type = PowerPoint.PpBulletType.ppBulletNumbered;
                                   break;
                               case 2:
                                   paragraph.ParagraphFormat.Bullet.Type = PowerPoint.PpBulletType.ppBulletUnnumbered;
                                   paragraph.ParagraphFormat.Bullet.Character = myparagraph.BulletValue;
                                   break;
                           }
                           
                       }                   
                       
                       switch (((TextContent)contentList[i]).Alignment)
                       {
                           case 0:
                               text.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentLeft;
                               break;
                           case 1:
                               text.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered;
                               break;
                           case 2:
                               text.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentRight;
                               break;
                       }
                       textcurrY += text.Height;
                    }
                }
            }
            if (level < 2)
            {
                InsertIntroSlide(objSlides, ref indexslide, objSlide);
            }
            if (this.childrenNodeList != null)
            {
                int count = this.childrenNodeList.Count;
                for (int i = 0; i < count; i++)
                {
                    indexslide ++;
                    this.childrenNodeList[i].AddNodeToSlide(objSlides,ref indexslide);
                    
                }
            }
           
        }

       private void InsertIntroSlide(PowerPoint.Slides objSlides, ref int indexslide, PowerPoint.Slide _objSlide)
       {
           if(this.childrenNodeList.Count <2)
           {
               return;
           }
           System.Windows.Forms.RichTextBox textbox = new RichTextBox();
           PowerPoint.Slide objSlide = null;
           if (this.contentList.Count == 0 )
           {
               objSlide = _objSlide;
           }
           else
           {
               indexslide++;
               objSlide = objSlides.Add(indexslide, PowerPoint.PpSlideLayout.ppLayoutText);
               PowerPoint.TextRange objTextRng = objSlide.Shapes[1].TextFrame.TextRange;

               objTextRng.Text = this.name;

               objTextRng.Font.Name = "Comic Sans MS";
               objTextRng.Font.Size = 48;
           }

           if (this.childrenNodeList != null)
           {
               PowerPoint.Shape text = objSlide.Shapes[2];    
               int count = this.childrenNodeList.Count;
               foreach (Node item in childrenNodeList)
               {
                   
                   PowerPoint.TextRange paragraph = text.TextFrame.TextRange.InsertAfter(item.name+"\n"); 
                   paragraph.IndentLevel = 2;
                  
               }
           }
           
       }

        private int StringToColor(string _color)
        {
            int rs;
            
            try
            {
                int alpha = int.Parse(_color.Substring(0, 2));
                int red = int.Parse(_color.Substring(2, 2));
                int green = int.Parse(_color.Substring(4,2 ));
                int blue = int.Parse(_color.Substring(6, 2));
                rs = System.Drawing.Color.FromArgb(alpha,red, green, blue).ToArgb();
            }
            catch {
                rs = System.Drawing.Color.FromArgb(0, 0, 0).ToArgb();
            }
            
            return rs;
        }

        public void CheckChildNode()
        {
            ErrorType errorType = ErrorTypesHelper.GetInstance().GetErrorTypeByName("ChildNodeError");
            if (this.childrenNodeList.Count >= errorType.Boundary)
            {
                if (this.errorList == null)
                    this.errorList = new List<int>();
                this.AddError(errorType.Id);
            }
            else
            {
                if(this.errorList!=null && this.errorList.Contains(errorType.Id))
                {
                    this.errorList.Remove(errorType.Id);
                }
            
            }
        }

        public void CheckContent()
        {
            ErrorType errorType = ErrorTypesHelper.GetInstance().GetErrorTypeByName("ContentError");
            //MessageBox.Show(this.contentList.Count.ToString());
            if (this.contentList.Count >= errorType.Boundary)
            {
                if (this.errorList == null)
                    this.errorList = new List<int>();
                this.AddError(errorType.Id);
                return;
                // MessageBox.Show(this.contentList.Count.ToString());
            }
            else
            {
                if (this.errorList != null)
                {
                    foreach (int i in errorList)
                    {
                        if (i == errorType.Id)
                        {
                            errorList.Remove(i);
                            return;
                        }
                    }
                }
            }
        }

        virtual public void CheckLevel()
        {
            ErrorType errorType = ErrorTypesHelper.GetInstance().GetErrorTypeByName("LevelError");
            if (this.ComputeLevel() >= errorType.Boundary)
            {
                this.AddError(errorType.Id);
                
            }
            else 
            {
                if (this.errorList != null)
                {
                    if (errorList.Contains(errorType.Id))
                    {
                        errorList.Remove(errorType.Id);
                    }
                }
            }
            CheckParentError();

        }
        public void CheckParentError()
        {
            if (this.ParentNode != null)
            {
                ErrorType errorType = ErrorTypesHelper.GetInstance().GetErrorTypeByName("LevelError");
                if (this.parentNode.ComputeLevel() > errorType.Boundary)
                {
                    this.ParentNode.AddError(errorType.Id);
                    
                }
                else
                {
                    if (this.parentNode.errorList != null)
                    {
                        if(this.parentNode.errorList.Contains(errorType.Id))
                            this.parentNode.errorList.Remove(errorType.Id);
                    }
                }
                this.parentNode.CheckParentError();
            }
        }

        public int ComputeLevel()
        {
            int itOwnLevel = 1 ;
            if (this.parentNode == null)
            {
                itOwnLevel = 1;
                return itOwnLevel;
            }
            else
            {
                itOwnLevel = parentNode.ComputeLevel() + 1;
            }
            return itOwnLevel;
        }

        public bool DelecteNode(Node _node)
        {
            foreach (Node node in ChildrenNodeList)
            {
                if (node.Name.Equals(_node.name))
                {
                    this.childrenNodeList.Remove(node);
                    this.CheckLevel();
                    this.CheckContent();
                    this.CheckChildNode();
                    return true;
                }
                else
                {
                    node.DelecteNode(_node);
                }
            }
            return false;
        }

        public   bool Equals (Node _node)
        {
            if (this.x == _node.x && this.y == _node.y && this.name.Equals(_node.name))
                return true;
            return false;
        }

        public void Down()
        {
            if (parentNode != null)
            {
                int currentIndex = parentNode.childrenNodeList.IndexOf(this);
                if (currentIndex < parentNode.childrenNodeList.Count -1)
                {
                    Node nextNode = parentNode.childrenNodeList.ElementAtOrDefault(currentIndex + 1);
                    Node currentNode = this;
                    parentNode.childrenNodeList[currentIndex] = nextNode;
                    parentNode.childrenNodeList[currentIndex + 1] = currentNode;
                }
                parentNode.UpdateChildOrder();
            }
        }

        public void Up()
        {            
            if (parentNode != null)
            {
                int currentIndex = parentNode.childrenNodeList.IndexOf(this);
                if (currentIndex > 0)
                {
                    Node preNode = parentNode.childrenNodeList.ElementAtOrDefault(currentIndex - 1);
                    Node currentNode = this;
                    parentNode.childrenNodeList[currentIndex] = preNode;
                    parentNode.childrenNodeList[currentIndex-1] = currentNode;
                }
                parentNode.UpdateChildOrder();
            }
        }

        private string strColor = @"#FF058670";

        public string StrColor
        {
            get { return strColor; }
            set { strColor = value; }
        }
        public void UpdateOrder(int level)
        {
            foreach (Node item in this.childrenNodeList)
            {
                item.Order = this.childrenNodeList.IndexOf(item) + 1;
                item.Level = level + 1;
                switch (level)
                {
                    case 0:
                        item.Color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#FFE821E8");
              
                        break;
                    case 1:
                        item.Color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#FF11AAAA");
              
                        
                        break;
                    case 2:
                        item.Color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#FFE86E21");
                        
                        break;
                    case 3:
                        item.Color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#FF090990");
                        break;
                    case 4:
                        item.Color = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#FF058670");
                        break;
                    
                    default: break;
                }
                item.UpdateOrder(level + 1);
            }
        }
        public void UpdateChildOrder()
        {
            foreach (Node item in this.childrenNodeList)
            {
                item.Order = this.childrenNodeList.IndexOf(item) + 1;
                
            }
        }
    }
}
